home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / lang / fpcsrc.lha / fpc / compiler / pmodules.pas < prev    next >
Pascal/Delphi Source File  |  1998-09-24  |  44KB  |  1,189 lines

  1. {
  2.     $Id: pmodules.pas,v 1.2.2.6 1998/09/14 18:58:09 carl Exp $
  3.     Copyright (c) 1998 by Florian Klaempfl
  4.  
  5.     Handles the parsing and loading of the modules (ppufiles)
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  ****************************************************************************
  22. }
  23. unit pmodules;
  24.  
  25.   interface
  26.  
  27.     uses
  28.        dos,strings,
  29.        cobjects,globals,scanner,symtable,aasm,tree,pass_1,
  30.        types,hcodegen,files,verbose,systems,link,assemble
  31. {$ifdef GDB}
  32.        ,gdb
  33. {$endif GDB}
  34.        { parser specific stuff }
  35.        ,pbase,pdecl,pstatmnt,psub
  36.        { processor specific stuff }
  37. {$ifdef i386}
  38.        ,i386
  39.        ,cgai386
  40.        ,tgeni386
  41.        ,cgi386
  42.        ,aopt386
  43. {$endif}
  44. {$ifdef m68k}
  45.        ,m68k
  46.        ,cga68k
  47.        ,tgen68k
  48.        ,cg68k
  49. {$endif}
  50.        ;
  51.  
  52.     function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
  53.     procedure proc_unit;
  54.     procedure proc_program(islibrary : boolean);
  55.  
  56.   implementation
  57.  
  58.     uses
  59.        parser;
  60.  
  61.     {$I innr.inc}
  62.  
  63.     procedure insertinternsyms(p : psymtable);
  64.  
  65.       begin
  66.          p^.insert(new(psyssym,init('CONCAT',in_concat_x)));
  67.          p^.insert(new(psyssym,init('WRITE',in_write_x)));
  68.          p^.insert(new(psyssym,init('WRITELN',in_writeln_x)));
  69.          p^.insert(new(psyssym,init('ASSIGNED',in_assigned_x)));
  70.          p^.insert(new(psyssym,init('READ',in_read_x)));
  71.          p^.insert(new(psyssym,init('READLN',in_readln_x)));
  72.          p^.insert(new(psyssym,init('OFS',in_ofs_x)));
  73.          p^.insert(new(psyssym,init('SIZEOF',in_sizeof_x)));
  74.          p^.insert(new(psyssym,init('TYPEOF',in_typeof_x)));
  75.          p^.insert(new(psyssym,init('LOW',in_low_x)));
  76.          p^.insert(new(psyssym,init('HIGH',in_high_x)));
  77.          p^.insert(new(psyssym,init('SEG',in_seg_x)));
  78.          p^.insert(new(psyssym,init('ORD',in_ord_x)));
  79.          p^.insert(new(psyssym,init('PRED',in_pred_x)));
  80.          p^.insert(new(psyssym,init('SUCC',in_succ_x)));
  81.  
  82.          { for testing purpose }
  83.          p^.insert(new(psyssym,init('DECI',in_dec_x)));
  84.          p^.insert(new(psyssym,init('INCI',in_inc_x)));
  85.          p^.insert(new(psyssym,init('STR',in_str_x_string)));
  86.       end;
  87.  
  88.     procedure load_ppu(oldhp,hp : pmodule;compile_system : boolean);
  89.  
  90.       var
  91.          loaded_unit  : pmodule;
  92.          b            : byte;
  93.          checksum,
  94.          count,
  95.          nextmapentry : longint;
  96.          hs           : string;
  97.          w1,w2        : word;
  98.       begin
  99.          { init the map }
  100.          new(hp^.map);
  101.          nextmapentry:=1;
  102.  
  103.          { load the used units from interface }
  104.          hp^.ppufile^.read_data(b,1,count);
  105.          while (b=ibloadunit) do
  106.            begin
  107.               { read unit name }
  108.               hp^.ppufile^.read_data(hs[0],1,count);
  109.               hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
  110.               hp^.ppufile^.read_data(checksum,4,count);
  111. {$ifdef BIG_ENDIAN}
  112.               w1:=checksum and $ffff;
  113.               w2:=checksum shr 16;
  114.               checksum:=swap(w2)+(longint(swap(w1)) shl 16);
  115. {$endif}
  116.               loaded_unit:=loadunit(hs,false,false);
  117.               if hp^.compiled then
  118.                 exit;
  119.               { if the crc of a used unit is the same as }
  120.               { written to the PPU file, we needn't to   }
  121.               { recompile the current unit               }
  122.               if (loaded_unit^.crc<>checksum) or
  123.                  (do_build and loaded_unit^.sources_avail) then
  124.                 begin
  125.                    { we have to compile the current unit }
  126.                    { remove stuff which isn't needed     }
  127.                    { forget the map }
  128.                    dispose(hp^.map);
  129.                    hp^.map:=nil;
  130.                    hp^.ppufile^.close;
  131.                    dispose(hp^.ppufile,done);
  132.                    hp^.ppufile:=nil;
  133.                    if assigned(oldhp^.current_inputfile) then
  134.                      oldhp^.current_inputfile^.tempclose;
  135.                    compile(hp^.mainsource^,compile_system);
  136.                    if (not oldhp^.compiled) and assigned(oldhp^.current_inputfile) then
  137.                      oldhp^.current_inputfile^.tempreopen;
  138.                    exit;
  139.                 end;
  140.               { setup the map entry for deref }
  141.               hp^.map^[nextmapentry]:=loaded_unit^.symtable;
  142.               inc(nextmapentry);
  143.  
  144.               if nextmapentry>maxunits then
  145.                Message(unit_f_too_much_units);
  146.  
  147.               { read until ibend }
  148.               hp^.ppufile^.read_data(b,1,count);
  149.            end;
  150.  
  151.          { ok, now load the unit }
  152.          hp^.symtable:=new(punitsymtable,load(hp^.unitname^));
  153.  
  154.          { if this is the system unit insert the intern }
  155.          { symbols                                      }
  156.          if compile_system then
  157.            insertinternsyms(psymtable(hp^.symtable));
  158.  
  159.          { now only read the implementation part }
  160.          hp^.in_implementation:=true;
  161.  
  162.          { load the used units from implementation }
  163.          hp^.ppufile^.read_data(b,1,count);
  164.          while (b<>ibend) and (b=ibloadunit) do
  165.            begin
  166.               { read unit name }
  167.               hp^.ppufile^.read_data(hs[0],1,count);
  168.               hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
  169.               hp^.ppufile^.read_data(checksum,4,count);
  170.               loaded_unit:=loadunit(hs,false,false);
  171.               if hp^.compiled then exit;
  172.               { if the crc of a used unit is the same as }
  173.               { written to the PPU file, we needn't to   }
  174.               { recompile the current unit               }
  175.               { but for the implementation part          }
  176.               { the written crc is false, because        }
  177.               { not defined when writing the ppufile !!  }
  178.               if {(loaded_unit^.crc<>checksum) or}
  179.                 (do_build and loaded_unit^.sources_avail) then
  180.                 begin
  181.                    { we have to compile the current unit }
  182.                    { remove stuff which isn't needed     }
  183.                    { forget the map }
  184.                    dispose(hp^.map);
  185.                    hp^.map:=nil;
  186.                    hp^.ppufile^.close;
  187.                    dispose(hp^.ppufile,done);
  188.                    hp^.ppufile:=nil;
  189.                    if not(hp^.sources_avail) then
  190.                     Message1(unit_f_cant_compile_unit,hp^.unitname^)
  191.                    else
  192.                      begin
  193.                         oldhp^.current_inputfile^.tempclose;
  194.                         compile(hp^.mainsource^,compile_system);
  195.                         oldhp^.current_inputfile^.tempclose;
  196.                      end;
  197.                    exit;
  198.                 end;
  199.               { read until ibend }
  200.               hp^.ppufile^.read_data(b,1,count);
  201.            end;
  202.          hp^.ppufile^.close;
  203.          dispose(hp^.map);
  204.          hp^.map:=nil;
  205.       end;
  206.  
  207.  
  208.     function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
  209.  
  210.       var
  211.          st : punitsymtable;
  212.          old_current_module,hp,nextmodule : pmodule;
  213.          pu : pused_unit;
  214.          a  : pasmfile;
  215.          hs : pstring;
  216.          i  : longint;
  217.       begin
  218.          old_current_module:=current_module;
  219.          { be sure not to mix lines from different files }
  220.          { update_line; }
  221.          { unit not found }
  222.          st:=nil;
  223.          { search all loaded units }
  224.          hp:=pmodule(loaded_units.first);
  225.          while assigned(hp) do
  226.            begin
  227.               if hp^.unitname^=s then
  228.                 begin
  229.                    { the unit is alr